/*********************************************************
*Copyright (c) 2009 Rob Groves. All Rights in Pw 
*@des: 异步并发TCP Sever 
*@name: Server.h
*@author: zhognsx
*@time: 2015-02-27
*********************************************************/
#ifndef _SERVER_H_
#define _SERVER_H_

#include "Global.h"
#include "msg.h"
#include <boost/asio.hpp>
#include <boost/bind.hpp>  
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp> 
#include <boost/noncopyable.hpp>
#include <boost/thread.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/enable_shared_from_this.hpp>


//ios线程池
class io_service_pool: public boost::noncopyable
{
public:
    explicit io_service_pool(std::size_t pool_size);

    void start();
    void join();
    void stop();

    boost::asio::io_service& get_io_service();
private:
    typedef boost::shared_ptr<boost::asio::io_service> io_service_sptr;
    typedef boost::shared_ptr<boost::asio::io_service::work> work_sptr;
    typedef boost::shared_ptr<boost::thread> thread_sptr;

    boost::mutex mtx;

    std::vector<io_service_sptr> io_services_;
    std::vector<work_sptr> work_;
    std::vector<thread_sptr> threads_;
    std::size_t next_io_service_;
};



//本地回调函数
//typedef boost::function<void(boost::system::error_code ec)> callback_t;
//解析MSG头数据, 并返回MSG数据长度; 若buf长满足body数据长, 处理MSG
//msg 
class session;
typedef boost::function<void(boost::shared_ptr<session>& , boost::shared_ptr<message>& ) > CallBack_SF;
typedef boost::function<void(boost::shared_ptr<session>& ) > CallBack_SE;

//简易session
class session: public boost::noncopyable, 
	public boost::enable_shared_from_this<session>
{
public:
	session(boost::asio::io_service& ios, CallBack_SF _func);
	virtual ~session();

	boost::asio::ip::tcp::socket& socket();
	//
	void start_read();
	//将消息主动投递给io_service  
	void write(boost::shared_ptr<message> msg);
	//这个close函数是客户端要主动终止时调用
	void close();

	void SetErrorCallBack(CallBack_SE _error); //设置错误回调
	inline std::string geterrstr() { return errstr; }
	void SetSessionInfo(string ip, short port);
private:
	//连接回调
	void handle_connect(const boost::system::error_code& error); 
	//处理数据报头 
	void handle_read_header(const boost::system::error_code& error, int bytes_);  
	//处理数据包数据
	void handle_read_msg(const boost::system::error_code& error, int bytes_);
	//把要写的数据push至写队列 
	void do_write(boost::shared_ptr<message> msg);
	//第一个消息单独处理，剩下的才更好操作 
	void handle_write(const boost::system::error_code& error);

	void do_close(); 
	//超时
	void time_out(const boost::system::error_code& error);
protected:
	//
	string sessionIp;
	short sessionPort;
	//超时timer
	boost::asio::deadline_timer timer_;
private:
	//错误信息
	std::string errstr;

	boost::asio::io_service& io_service_; 
	boost::asio::ip::tcp::socket socket_;
	//
	CallBack_SF func;
	//产生错误的回调处理函数
	CallBack_SE	error;

	boost::shared_ptr<message> read_buf_;
	std::list<boost::shared_ptr<message>> write_bufs_;   
};

//并发server
class server: public boost::noncopyable
{
public:
	//传入head_len 
	server(short port, CallBack_SF _func);
	
	//
	void run(); 

	void handle_accept(boost::shared_ptr<session>& new_session, 
			const boost::system::error_code& error);
private:
	std::vector<boost::shared_ptr<session> > sesion_vec;
	//
	CallBack_SF func;
	//boost::asio::io_service ios;
	io_service_pool io_service_pool_;
	boost::asio::ip::tcp::acceptor acceptor_; 
};


#endif //_SERVER_H_
